#ifndef _EKOS_ENV_H_
#define _EKOS_ENV_H_

#include <inc/types.h>

#include <inc/exception.h>
#include <inc/memlayout.h>
#include <inc/iec.h>

/* environment 是 EKOS 的基本调度单位 */

/* 任务调度所需要的结构 */
struct sched_info_t
{
     /* 环状列表 */
     uint16_t next;
     uint16_t prev;
     
//	 /* 当前还剩下多少时间片 */
//	 int16_t time_last;
	 /* 睡眠邻接状态的替换索引 */
	 uint16_t sleep_rep;
};

struct env_t
{
	 /* current status */
     uint16_t env_status;

	 union {

		  // statue: in use
		  struct {

			   /* 在这里我们认为, 在系统的生命周期中, 所有环境的编号各自不同 */
			   uint32_t eid;
		  
			   /* sub-process ID */
			   uint16_t lid;
		  
			   /* parent index */
			   uint16_t parent;
			   /* a flag indicates that whether we are in kern */
			   uint16_t inkern;

			   uint16_t sch_status;
			   /* for current simple scheduler */
			   struct sched_info_t sched_info;
		  
			   /* 页表地址 */
			   physaddr_t cr3;
		  
			   /* 发送信号的锁 */
			   uint8_t signal_lock;
			   /* 信号的暂存器 */
			   uint16_t signal;
		  
			   /* 信号处理程序 */
			   uint32_t signal_handler;
		  
			   /* stack pointer when switch in */
			   GPREG_T ssp;
			   /* kernel stack pointer */
			   uint32_t ksp;
		  
			   /* 杀死锁 */
			   uint8_t kill_lock;
		  
			   /* 权限标志, 目前涉及 RPC 以及端口权限 */
			   uint16_t perm_flag;
			   /* 权限等级, IEC 的时候使用 */
			   uint16_t perm_level;
		  
			   /* IEC 信息 */
			   struct iec_info_t iec;
		  
			   /* exception level and user exception stack pointer */
			   struct user_xinfo_t xinfo;
		  };

		  // status: free
		  uint16_t free_next;
	 };
};

/* Status of env */
#define ENV_FREE            0		/* free for alloc */
#define ENV_INUSE           1

#define ENV_SCH_DETACHED        0
#define ENV_SCH_WAITING         1		/* waiting for switching */
#define ENV_SCH_RUNNING         2		/* current env */
#define ENV_SCH_SLEEPING        3

#define ENV_SCH_IEC_RECV_BLOCKING 4
#define ENV_SCH_IEC_SEND_BLOCKING 5

/* 最大允许的环境数 */
/* 此值与 memlayout 有关系, 详见相关文档 */
#define ENVS_MAXCOUNT       (PAGETAB_COUNT)
#define ENV_NULL            ((uint16_t)0xffff)

#endif /* _EKOS_ENV_H_ */
